﻿using System;
using KryptecizerBase.Encryption;
using KryptecizerBase.Decryption;
using KryptecizerBase.EventArguments;

namespace KryptecizerBase
{
    /// <summary>
    /// TextBasedKryptObject for de- and encryption of texts.
    /// </summary>
    public class TextBasedKryptObject : KryptBaseObject
    {
        #region Member
        private KryptoText _KryptoTextDecrypted;
        private KryptoText _KryptoTextEncrypted;
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the krypto text decrypted.
        /// </summary>
        /// <value>The krypto text decrypted.</value>
        public KryptoText kryptoTextDecrypted
        {
            get { return _KryptoTextDecrypted; }
            set {   
                    _KryptoTextDecrypted = value;
                    OnDecryptedTextChanged();
                }
        }

        /// <summary>
        /// Gets or sets the krypto text encrypted.
        /// </summary>
        /// <value>The krypto text encrypted.</value>
        public KryptoText kryptoTextEncrypted
        {
            get { return _KryptoTextEncrypted; }
            set { 
                    _KryptoTextEncrypted = value;
                    OnEncryptedTextChanged();
                }
        }
        #endregion

        #region Constructor
        /// <summary>
        /// Initializes a new instance of the <see cref="TextBasedKryptObject"/> class.
        /// </summary>
        public TextBasedKryptObject()
        {
            _KryptoTextDecrypted = new KryptoText();
            _KryptoTextDecrypted.Changed += new KryptoText.ChangedEventHandler(_KryptoTextDecrypted_Changed);
            _KryptoTextEncrypted = new KryptoText();
            _KryptoTextEncrypted.Changed += new KryptoText.ChangedEventHandler(_KryptoTextEncrypted_Changed);
        }

        void _KryptoTextEncrypted_Changed()
        {
            OnEncryptedTextChanged();
        }

        void _KryptoTextDecrypted_Changed()
        {
            OnDecryptedTextChanged();
        }
        #endregion

        #region public methods
        /// <summary>
        /// Method to decrypts the kryptoTextEncrypted with the specified decryptor.
        /// </summary>
        /// <param name="decryptor">The decryptor.</param>
        /// <returns>success</returns>
        public override bool Decrypt(KryptecizerBase.Decryption.Decryptor decryptor)
        {
            (decryptor as KryptoTextDecryptor).DecryptedKryptoText = _KryptoTextEncrypted.Clone();
            (decryptor as KryptoTextDecryptor).DecryptionProcessing += new Decryptor.DecryptionProcessingEventHandler(TextBasedKryptObject_DecryptionProcessing);
            (decryptor as KryptoTextDecryptor).Decrypt();
            return true;
        }

        /// <summary>
        /// Method for DecryptionProcessingEventHandler.
        /// </summary>
        /// <param name="percentDone">The percent done.</param>
        void TextBasedKryptObject_DecryptionProcessing(int percentDone)
        {
            OnWorkPercentProcessed(percentDone);
        }

        /// <summary>
        /// Method to encrypts the kryptoTextDecrypted with the specified encryptor.
        /// </summary>
        /// <param name="encryptor">The encryptor.</param>
        /// <returns>success</returns>
        public override bool Encrypt(KryptecizerBase.Encryption.Encryptor encryptor)
        {
            (encryptor as KryptoTextEncryptor).EncryptedKryptoText = _KryptoTextDecrypted.Clone();
            (encryptor as KryptoTextEncryptor).EncryptionProcessing += new Encryptor.EncryptionProcessingEventHandler(TextBasedKryptObject_EncryptionProcessing);
            (encryptor as KryptoTextEncryptor).Encrypt();
            return true;
        }

        /// <summary>
        /// Method for EncryptionProcessingEventHandler.
        /// </summary>
        /// <param name="percentDone">The percent done.</param>
        void TextBasedKryptObject_EncryptionProcessing(int percentDone)
        {
            OnWorkPercentProcessed(percentDone);
        }
        #endregion

        #region private methods
        private void OnDecryptedTextChanged()
        {
            if (DecryptedTextChanged != null)
                DecryptedTextChanged(new TextChangedEventArgs(_KryptoTextDecrypted.GetAsString()));
        }

        private void OnEncryptedTextChanged()
        {
            if (EncryptedTextChanged != null)
                EncryptedTextChanged(new TextChangedEventArgs(_KryptoTextEncrypted.GetAsString()));
        }

        private void OnWorkPercentProcessed(int percentDone)
        {
            if (WorkPercentProcessed != null)
                WorkPercentProcessed(percentDone);
        }
        #endregion

        #region events and delegates
        /// <summary>
        /// Handles the DecryptedTextChanged event.
        /// </summary>
        public delegate void DecryptedTextChangedHandler(TextChangedEventArgs arg);
        /// <summary>
        /// Occurs when [decrypted text changed].
        /// </summary>
        public event DecryptedTextChangedHandler DecryptedTextChanged;

        /// <summary>
        /// Handles the EncryptedTextChanged event.
        /// </summary>
        public delegate void EncryptedTextChangedHandler(TextChangedEventArgs arg);
        /// <summary>
        /// Occurs when [encrypted text changed].
        /// </summary>
        public event EncryptedTextChangedHandler EncryptedTextChanged;

        /// <summary>
        /// Handles the WorkPercentProcessed event.
        /// </summary>
        public delegate void WorkPercentProcessedHandler(int percentDone);
        /// <summary>
        /// Occurs when [work percent processed].
        /// </summary>
        public event WorkPercentProcessedHandler WorkPercentProcessed;
        #endregion
    }
}
